const blog = require("../dao/blogDao");
const blogType = require("../dao/blogTypeDao");
const comment = require("../dao/commentDao");
const validate = require("validate.js");
const { ValidationError } = require("../utils/errors");
const { getMarkDownTOC } = require("../utils/tool");

//自定义验证分类规则
validate.validators.categoryIdVerify = async (id) => {
  const blogTypeInfo = await blogType.oneBlogType(id);
  if (blogTypeInfo) {
    return;
  } else {
    return "categoryId Is Not Exist";
  }
};

//添加文章
const addBlog = async (blogInfo) => {
  if (!blogInfo.markdownContent) {
    throw new ValidationError("数据验证不通过");
  }
  //处理TOC
  blogInfo = getMarkDownTOC(blogInfo);
  blogInfo.toc = JSON.stringify(blogInfo.toc);

  //其他处理
  blogInfo.scanNumber = 0; //浏览量初始化为0
  blogInfo.commentNumber = 0; //评论数初始化为0
  const rule = {
    title: {
      presence: {
        allowEmpty: false,
      },
      type: "string",
    },
    description: {
      presence: {
        allowEmpty: true,
      },
      type: "string",
    },
    toc: {
      presence: {
        allowEmpty: true,
      },
      type: "string",
    },
    htmlContent: {
      presence: {
        allowEmpty: false,
      },
      type: "string",
    },
    thumb: {
      presence: {
        allowEmpty: true,
      },
      type: "string",
    },
    creatDate: {
      presence: {
        allowEmpty: false,
      },
      type: "integer",
    },
    categoryId: {
      presence: true,
      type: "integer",
      categoryIdVerify: true,
    },
    scanNumber: {
      presence: {
        allowEmpty: false,
      },
      type: "integer",
    },
    commentNumber: {
      presence: {
        allowEmpty: false,
      },
      type: "integer",
    },
  };

  try {
    await validate.async(blogInfo, rule);
    const data = await blog.addBlog(blogInfo);
    const { categoryId } = data.toJSON();
    await blogType.addArticleCount(categoryId); //文章所除分类文章 数量加一
    const result = data.toJSON();
    result.toc = JSON.parse(result.toc);
    return result;
  } catch (err) {
    console.log(err, "123123");
    throw new ValidationError("数据验证错误");
  }
};

//删除文章
const deleteBlog = async (id) => {
  //该文章上分类数量自减
  const { categoryId } = await blog.getBlog(id);
  await blogType.reduceArticleCount(categoryId);
  //删除该文章下所以评论
  await comment.deleteBlogCommentAll(id);
  //删除文章
  await blog.deleteBlog(id);
  return true;
};

//修改文章
const updateBlog = async (id, BlogInfo) => {
  //判断是否需要进行TOC处理
  if (BlogInfo.htmlContent && BlogInfo.markdownContent) {
    //处理TOC
    BlogInfo = getMarkDownTOC(BlogInfo);
    BlogInfo.toc = JSON.stringify(BlogInfo.toc);
  }

  const rule = {
    title: {
      type: "string",
    },
    description: {
      type: "string",
    },
    toc: {
      type: "string",
    },
    htmlContent: {
      type: "string",
    },
    thumb: {
      type: "string",
    },
    creatDate: {
      type: "integer",
    },
    categoryId: {
      presence: true,
      type: "integer",
      categoryIdVerify: true,
    },
    scanNumber: {
      type: "integer",
    },
    commentNumber: {
      type: "integer",
    },
  };
  try {
    await validate.async(BlogInfo, rule);
    if (BlogInfo.categoryId) {
      //之前所属文章分类的文章数量自减
      const { categoryId } = await blog.getBlog(id);
      await blogType.reduceArticleCount(categoryId);
      //当前需要加入文章分类的文章数量自增
      await blogType.addArticleCount(BlogInfo.categoryId);
    }
    const data = await blog.updateBlog(id, BlogInfo);
    const result = data.toJSON();
    result.toc = JSON.parse(result.toc);
    return result;
  } catch (error) {
    throw new ValidationError("数据验证失败");
  }
};

//获取单篇文章
const getBlog = async (id, headers) => {
  const data = await blog.getBlog(id);

  //判断是否需要自增浏览量
  if (!headers.lenght) {
    //前台进入
    await blog.addScanNumber(id);
  }
  const result = data.toJSON();
  result.toc = JSON.parse(result.toc);
  return result;
};

//分页获取文章
const getBlogList = async (
  page = 1,
  limit = 10,
  keyword = "",
  categoryId = 0
) => {
  const rule = {
    page: {
      presence: {
        allowEmpty: false,
      },
      type: "integer",
    },
    limit: {
      presence: {
        allowEmpty: false,
      },
      type: "integer",
    },
    keyword: {
      presence: {
        allowEmpty: true,
      },
      type: "string",
    },
    categoryId: {
      presence: true,
      type: "integer",
    },
  };
  try {
    await validate.async({ page, limit, keyword, categoryId }, rule);
    const { count, rows: data } = await blog.getBlogList(
      page,
      limit,
      keyword,
      categoryId
    );
    //处理返回格式
    const rows = JSON.parse(JSON.stringify(data));
    rows.forEach((item) => {
      item.toc = JSON.parse(item.toc);
    });

    return {
      total: count,
      rows,
    };
  } catch (error) {
    throw new ValidationError("数据验证错误");
  }
};

module.exports = {
  addBlog,
  deleteBlog,
  updateBlog,
  getBlog,
  getBlogList,
};
